home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / GNU Chess 3.0.3 / src / mac.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-26  |  31.9 KB  |  1,534 lines  |  [TEXT/CWIE]

  1. /*
  2.   Mac interface for GNU Chess
  3.  
  4.   Revision: 10 Feb 1991
  5.  
  6.   Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
  7.   Copyright (c) 1991  Airy ANDRE
  8.  
  9.     expanded game save, list, and restore features
  10.     optional auto-updating of positional information
  11.  
  12.   This file is part of CHESS.
  13.  
  14.   CHESS is distributed in the hope that it will be useful,
  15.   but WITHOUT ANY WARRANTY.  No author or distributor
  16.   accepts responsibility to anyone for the consequences of using it
  17.   or for whether it serves any particular purpose or works at all,
  18.   unless he says so in writing.  Refer to the CHESS General Public
  19.   License for full details.
  20.  
  21.   Everyone is granted permission to copy, modify and redistribute
  22.   CHESS, but only under the conditions described in the
  23.   CHESS General Public License.   A copy of this license is
  24.   supposed to have been given to you along with CHESS so you
  25.   can know your rights and responsibilities.  It should be in a
  26.   file named COPYING.  Among other things, the copyright notice
  27.   and this notice must be preserved on all copies.
  28.   */
  29.  
  30. #include <stdio.h>
  31. #include "math.h"
  32.  
  33. #include "DragMgr.h"
  34. #include "gnuchess.h"
  35. #include "macintf.h"
  36.  
  37.  
  38. char mvstr[5][6];
  39. long evrate;
  40.  
  41. short PositionFlag = 0;
  42. short coords = 1;
  43. short stars = 0;
  44. short rv = 1;
  45. short shade = 0;
  46. short preview = 0;
  47. short idoit = 0;
  48. short drawn = 0;
  49. short undo = 0;
  50. short anim = 1;
  51. short showvalue = 0;
  52. short newgame = 0;
  53. short getgame = 0;
  54. short wne;
  55.  
  56. char buff[100];
  57.  
  58. Boolean    Finished;
  59. CursHandle    ClockCursor;
  60. CursHandle    ArrowCursor;
  61. CursHandle    CrossCursor;
  62. Rect    DragArea;
  63. Rect    GrowArea;
  64. MenuHandle    Menu;
  65. WindowPtr    WindBoard, WindList, WindThink;
  66. int    width,height;
  67.  
  68. short background = 0;
  69.  
  70. Point    thePoint;
  71. Rect    MinSize;
  72.     
  73. Rect    nameRec, ValueRec, ValueFRec,chessRectOff;
  74.  
  75. Rect    MsgRec, MsgFRec;
  76. Rect    ThinkRec[2], ThinkFRec[2];
  77. Rect     ScoreRec, ScoreFRec;
  78.  
  79. int     theScore;
  80. Str255    Msg;
  81.  
  82. Str255    ThinkMove[2][30];
  83. int        maxThink;
  84.  
  85. DragHandle    myDragStuff;
  86. Point    pt;
  87.  
  88. Pattern blackPat, whitePat;
  89.  
  90. Rect    CaseRec, CaseFRec;
  91. int        MouseX, MouseY;
  92.  
  93. int     ref;
  94. long    nbre;
  95.  
  96. short saveBoard[64], saveColor[64];
  97.  
  98. int towho;
  99.  
  100. ListHandle List;
  101. Rect theBar;
  102.  
  103.  
  104. void SetUpThing(void)
  105. {    
  106.     short typ,err,i,j;
  107.     Handle Hitem;
  108.     Rect r;
  109.  
  110.     FlushEvents(everyEvent,0);
  111.  
  112.     MoreMasters();
  113.     MoreMasters();
  114.     MoreMasters();
  115.     MoreMasters();
  116.     MoreMasters();
  117.     MaxApplZone();
  118.  
  119.     InitGraf(&qd.thePort);
  120.     InitFonts();
  121.     InitWindows();
  122.     InitMenus();
  123.     TEInit();
  124.     InitDialogs(0L);
  125.     InitUPPs();
  126.  
  127.     ClockCursor=GetCursor(watchCursor);
  128.     ArrowCursor=GetCursor(1000);
  129.     HNoPurge((Handle)ClockCursor);
  130.     HNoPurge((Handle)ArrowCursor);
  131.     SetCursor(*ClockCursor);
  132.     
  133.     StuffHex(&blackPat, "\pFFFFFFFFFFFFFFFF");
  134.     StuffHex(&whitePat, "\p0000000000000000");
  135.  
  136. #define WNETrapNum 0x60
  137. #define UnImplTrapNum 0x9F
  138.  
  139.     wne = NGetTrapAddress(WNETrapNum, ToolTrap) ==
  140.                     NGetTrapAddress(UnImplTrapNum, ToolTrap);
  141. }
  142.  
  143. void SetupMenus(void)
  144. {
  145.     MenuHandle MenuTopic ;
  146.     short index;
  147.  
  148.     MenuTopic=GetMenu(AppleMenu);
  149.     AddResMenu(MenuTopic,'DRVR');
  150.     InsertMenu(MenuTopic,0);
  151.  
  152.     for (index=FileMenu; index<=OptionsMenu; index++)
  153.             InsertMenu(GetMenu(index),0);
  154.  
  155.     InsertMenu(GetMenu(BlackMenu),-1);
  156.     InsertMenu(GetMenu(WhiteMenu),-1);
  157.  
  158.     DrawMenuBar();
  159. }
  160.  
  161.  
  162. void
  163. ShowPMessage (char *s)
  164. {
  165.   BlockMove(s, Msg, (long)*s + 1);
  166.   UpdateMsg(NULL, 3);
  167. }
  168.  
  169. void
  170. ShowCMessage (char *s)
  171. {
  172.   *Msg = strlen(s);
  173.   strcpy(Msg+1, s);
  174.   UpdateMsg(NULL, 3);
  175. }
  176.  
  177.  
  178. short RemoveMove(short GameCnt)
  179. {
  180.   Cell theCell;
  181.  
  182.   theCell.v = GameCnt/2;
  183.  
  184.   if (!(GameCnt&1)) {
  185.       LDelRow(1, theCell.v, List);
  186.   } else {
  187.       theCell.h = 1;
  188.       LClrCell(theCell, List);
  189.   }
  190.   
  191.   LScroll(0, 10000, List);
  192. }
  193.  
  194. short ShowError(short errno)
  195. {
  196.     StringHandle    theString;
  197.     short            returnVal;
  198.     
  199.     theString = GetString(errno);
  200.     HLock((Handle)theString);
  201.     ParamText(*theString, (ConstStr255Param)"", (ConstStr255Param)"", (ConstStr255Param)"");
  202.     returnVal = CautionAlert(_ERROR_ALRT, NULL);
  203.     HUnlock((Handle)theString);
  204.     return returnVal;
  205. }
  206.  
  207. short AreYouSure(short num)
  208. {
  209.     StringHandle    theString;
  210.     short            returnVal;
  211.     
  212.     theString = GetString(num);
  213.     HLock((Handle)theString);
  214.     ParamText(*theString, (ConstStr255Param)"", (ConstStr255Param)"", (ConstStr255Param)"");
  215.     returnVal = CautionAlert(_CONFIRM_ALRT, NULL);
  216.     HUnlock((Handle)theString);
  217.     return returnVal == 2;
  218. }
  219.  
  220. char choosePromo()
  221. {
  222.     short item;
  223.     DialogPtr theDlog;
  224.     
  225.     theDlog = GetNewDialog(_PROMO_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  226.     
  227.     SetPort(theDlog);
  228.     
  229.     ModalDialog(NULL, &item);
  230.     
  231.     DisposDialog(theDlog);
  232.     
  233.     switch (item) {
  234.         case 1: return 'Q';
  235.         case 2: return 'N';
  236.         case 3: return 'R';
  237.         case 4: return 'B';
  238.     }
  239. }
  240.  
  241. short chooseTime(short *moves, short *minutes)
  242. {
  243.     short item;
  244.     DialogPtr theDlog;
  245.     Str255 str;
  246.     long res;
  247.     Handle hdl;
  248.     Rect theRect;
  249.     short type;
  250.     
  251.     theDlog = GetNewDialog(_TIME_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  252.     
  253.     GetDItem(theDlog, 6, (short *)&type, &hdl, &theRect);
  254.     NumToString(*moves, str);
  255.     SetIText(hdl, str);
  256.     GetDItem(theDlog, 5, (short *)&type, &hdl, &theRect);
  257.     NumToString(*minutes, str);
  258.     SetIText(hdl, str);
  259.     
  260.     SetPort(theDlog);
  261.     
  262.     
  263.     do {
  264.         ModalDialog(NULL, &item);
  265.     } while ((item != 1) && (item != 2));
  266.     
  267.     if (item == 1) {
  268.         GetDItem(theDlog, 6, &type, &hdl, &theRect);
  269.         GetIText(hdl, str);
  270.         StringToNum(str, &res);
  271.         *moves = res;
  272.         GetDItem(theDlog, 5, &type, &hdl, &theRect);
  273.         GetIText(hdl, str);
  274.         StringToNum(str, &res);
  275.         *minutes = res;
  276.     }
  277.     
  278.     DisposDialog(theDlog);
  279.     
  280.     return (item==1);
  281. }
  282.  
  283. short AddMove(short GameCnt, char *mvstr)
  284. {
  285.   Cell theCell;
  286.   char mv[10];
  287.  
  288.   theCell.v = GameCnt/2;
  289.  
  290.   if (!(GameCnt&1)) {
  291.     short num = theCell.v + 1;
  292.     
  293.       theCell.h = 0;
  294.       LAddRow(1, theCell.v, List);
  295.       mv[0] = (num / 100)?(num/100 + '0'):' ';
  296.       mv[1] = ((num % 100) / 10)?((num % 100)/10 + '0'):' ';
  297.       mv[2] = num%10 + '0';
  298.       mv[3] = '.';
  299.       strcpy(mv + 4, mvstr);
  300.   } else {
  301.       theCell.h = 1;
  302.       strcpy(mv, mvstr);
  303.   }
  304.   
  305.   LSetCell((Ptr)mv, strlen(mv), theCell, List);
  306.   LDraw(theCell, List);
  307.   LScroll(0, 10000, List);
  308. }
  309.  
  310.  
  311. void
  312. Initialize ()
  313. {
  314.  short    i,j;
  315.  Rect    r;
  316.  Handle Hitem;
  317.  Cell Csize;
  318.  Rect bound;
  319.  
  320.     SetRect(&DragArea,
  321.             qd.screenBits.bounds.left+4,
  322.             qd.screenBits.bounds.top+24,
  323.             qd.screenBits.bounds.right-4,
  324.             qd.screenBits.bounds.bottom-4);
  325.     SetRect(&GrowArea,
  326.             80,
  327.             qd.screenBits.bounds.top+60,
  328.             qd.screenBits.bounds.right,
  329.             qd.screenBits.bounds.bottom);
  330.     
  331.     WindBoard = GetNewDialog(770,(DialogPeek)0L,(WindowPtr)-1L);    
  332.     SetPort(WindBoard);
  333.     TextFont(geneva);
  334.     TextSize(9);
  335.     GetDItem(WindBoard, 1, &i, &Hitem, &chessRectOff);
  336.     SetDItem(WindBoard, 1, i, (Handle)UpdateGraphicUPP, &chessRectOff);
  337.     width = 1+(chessRectOff.right-chessRectOff.left)/8;
  338.     height = width;
  339.  
  340.     GetDItem(WindBoard, 2, &i, &Hitem, &CaseFRec);
  341.     SetDItem(WindBoard, 2, i, (Handle)UpdateCaseUPP, &CaseFRec);
  342.     CaseRec = CaseFRec;
  343.     InsetRect(&CaseRec, 1, 1);
  344.         
  345.     
  346.     WindThink = GetNewDialog(_THINK_DLOG,(DialogPeek)0L,(WindowPtr)-1L);
  347.     SetPort(WindThink);
  348.     TextFont(monaco);
  349.     TextSize(9);
  350.     
  351.     GetDItem(WindThink, 1, &i, &Hitem, &nameRec);
  352.     SetDItem(WindThink, 1, i,  (Handle)UpdateChronosUPP, &nameRec);
  353.     
  354.     GetDItem(WindThink, 5, &i, &Hitem, &ValueFRec);
  355.     SetDItem(WindThink, 5, i, (Handle)UpdateValueUPP, &ValueFRec);
  356.     ValueRec = ValueFRec;
  357.     InsetRect(&ValueRec, 1, 1);
  358.     
  359.     GetDItem(WindThink, 4, &i, &Hitem, &MsgFRec);
  360.     SetDItem(WindThink, 4, i, (Handle)UpdateMsgUPP, &MsgFRec);
  361.     MsgRec = MsgFRec;
  362.     InsetRect(&MsgRec, 1, 1);
  363.             
  364.     GetDItem(WindThink, 2, &i, &Hitem, &ThinkFRec[0]);
  365.     SetDItem(WindThink, 2, i, (Handle)UpdateThinkUPP, &ThinkFRec[0]);
  366.     ThinkRec[0] = ThinkFRec[0];
  367.     InsetRect(&ThinkRec[0], 1, 1);
  368.             
  369.     GetDItem(WindThink, 3, &i, &Hitem, &ThinkFRec[1]);
  370.     SetDItem(WindThink, 3, i, (Handle)UpdateThinkUPP, &ThinkFRec[1]);
  371.     ThinkRec[1] = ThinkFRec[1];
  372.     InsetRect(&ThinkRec[1], 1, 1);
  373.     
  374.     maxThink = (ThinkRec[1].bottom - ThinkRec[1].top - 5)/12 - 1;
  375.     
  376.     WindList = GetNewDialog(768, (DialogPeek)0L, (WindowPtr)-1L);
  377.     SetPort(WindList);
  378.     TextSize(9);
  379.     TextFont(monaco);
  380.     GetDItem(WindList, 1, &i, &Hitem, &r);
  381.     SetDItem(WindList, 1, i, (Handle)UpdateListeUPP, &r);
  382.     r.right -= 15;
  383.     Csize.v=12;Csize.h=(r.right-r.left)/2;
  384.     bound.top = 0;
  385.     bound.left = 0;
  386.     bound.right = 2;
  387.     bound.bottom = 0;
  388.     List=LNew(&r,&bound,Csize,0,WindList,TRUE,FALSE,FALSE,TRUE);
  389.  
  390.     theBar = r;
  391.     theBar.left = r.right;
  392.     theBar.right += 15;
  393.     
  394.        (**List).selFlags=lOnlyOne;
  395.                     
  396.     LAutoScroll(List);
  397.  
  398.     ShowWindow(WindList);
  399.     
  400.     SetPort(WindBoard);
  401.     MouseX = MouseY = 0;
  402.         
  403.     UpdateChronos(NULL, 2);
  404.     UpdateValue(NULL, 5);
  405.     UpdateMsg(NULL, 3);
  406.     UpdateCase(NULL, 4);
  407.     
  408.     SetPort(WindBoard);
  409.     InitDrag(0L, &chessRectOff);
  410.     UpdateDisplay(0,0,1,0,1,color,board);
  411.     
  412.     InitCursor();
  413. }
  414.  
  415. void
  416. ExitChess ()
  417. {
  418.   CloseDrag(0);
  419. }
  420.  
  421.  
  422. void
  423. algbr (f, t, flag)
  424.      short int f;
  425.      short int t;
  426.      short int flag;
  427. /*
  428.    Generate move strings in different formats, a hook has been provided for
  429.    underpromotion
  430. */
  431.  
  432. {
  433.   short m3p;
  434.  
  435.   if (f != t)
  436.     {
  437.       /* algebraic notation */
  438.       mvstr[0][0] = cxx[column (f)];
  439.       mvstr[0][1] = rxx[row (f)];
  440.       mvstr[0][2] = cxx[column (t)];
  441.       mvstr[0][3] = rxx[row (t)];
  442.       mvstr[0][4] = '\0';
  443.       mvstr[3][0] = '\0';
  444.       if ((mvstr[1][0] = qxx[board[f]]) == 'P')
  445.     {
  446.       if (mvstr[0][0] == mvstr[0][2])    /* pawn did not eat */
  447.         {
  448.           mvstr[2][0] = mvstr[1][0] = mvstr[0][2];    /* to column */
  449.           mvstr[2][1] = mvstr[1][1] = mvstr[0][3];    /* to row */
  450.           m3p = 2;
  451.         }
  452.       else
  453.         /* pawn ate */
  454.         {
  455.           mvstr[2][0] = mvstr[1][0] = mvstr[0][0];    /* from column */
  456.           mvstr[2][1] = mvstr[1][1] = mvstr[0][2];    /* to column */
  457.           mvstr[2][2] = mvstr[0][3];
  458.           m3p = 3;        /* to row */
  459.         }
  460.       mvstr[2][m3p] = mvstr[1][2] = '\0';
  461.       if (flag & promote)
  462.         {
  463.           mvstr[0][4] = mvstr[1][2] = mvstr[2][m3p] = qxx[flag & pmask];
  464.           mvstr[1][3] = mvstr[2][m3p + 1] = mvstr[0][5] = '\0';
  465.         }
  466.     }
  467.       else
  468.     /* not a pawn */
  469.     {
  470.       mvstr[2][0] = mvstr[1][0];
  471.       mvstr[2][2] = mvstr[1][1] = mvstr[0][2];    /* to column */
  472.       mvstr[2][3] = mvstr[1][2] = mvstr[0][3];    /* to row */
  473.       mvstr[2][4] = mvstr[1][3] = '\0';
  474.       mvstr[2][1] = mvstr[0][1];
  475.       strcpy (mvstr[3], mvstr[2]);
  476.       mvstr[3][1] = mvstr[0][0];
  477.       if (flag & cstlmask)
  478.         {
  479.           if (t > f)
  480.         {
  481.           strcpy (mvstr[1], "o-o");
  482.           strcpy (mvstr[2], "O-O");
  483.         }
  484.           else
  485.         {
  486.           strcpy (mvstr[1], "o-o-o");
  487.           strcpy (mvstr[2], "O-O-O");
  488.         }
  489.         }
  490.     }
  491.     }
  492.   else
  493.     mvstr[0][0] = mvstr[1][0] = mvstr[2][0] = mvstr[3][0] = '\0';
  494. }
  495.  
  496. void
  497. seteasy()
  498. {
  499.   easy = !easy;
  500. }
  501.  
  502.  
  503. short
  504. VerifyMove (s, iop, mv)
  505.      char *s;
  506.      short int iop;
  507.      short unsigned int *mv;
  508. /*
  509.    Compare the string 's' to the list of legal moves available for the
  510.    opponent. If a match is found, make the move on the board.
  511. */
  512. {
  513.   static short pnt, tempb, tempc, tempsf, tempst, cnt;
  514.   static struct leaf xnode;
  515.   struct leaf *node;
  516.  
  517.   *mv = 0;
  518.   if (iop == 2)
  519.     {
  520.       UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  521.       return (false);
  522.     }
  523.   cnt = 0;
  524.   MoveList (opponent, 2);
  525.   pnt = TrPnt[2];
  526.   while (pnt < TrPnt[3])
  527.     {
  528.       node = &Tree[pnt++];
  529.       algbr (node->f, node->t, (short) node->flags);
  530.       if (strcmp (s, mvstr[0]) == 0 || strcmp (s, mvstr[1]) == 0 ||
  531.           strcmp (s, mvstr[2]) == 0 || strcmp (s, mvstr[3]) == 0)
  532.         {
  533.           cnt++;
  534.           xnode = *node;
  535.         }
  536.     }
  537.   if (cnt == 1)
  538.     {
  539.       MakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst, 0);
  540.       if (SqAtakd (PieceList[opponent][0], computer))
  541.         {
  542.           UnmakeMove (opponent, &xnode, &tempb, &tempc, &tempsf, &tempst);
  543.           return (false);
  544.         }
  545.       else
  546.         {
  547.           if (iop == 1)
  548.             return (true);
  549.           if (xnode.flags & cstlmask)
  550.             Game50 = GameCnt;
  551.           else if (board[xnode.t] == pawn || (xnode.flags & capture))
  552.             Game50 = GameCnt;
  553.           GameList[GameCnt].depth = GameList[GameCnt].score = 0;
  554.           GameList[GameCnt].nodes = 0;
  555.           GameList[GameCnt].time = (short) et;
  556.           GameList[GameCnt].flags = xnode.flags;
  557.           TimeControl.clock[opponent] -= et;
  558.           --TimeControl.moves[opponent];
  559.           
  560.           ElapsedTime(1);
  561.  
  562.           *mv = (xnode.f << 8) + xnode.t;
  563.           algbr (xnode.f, xnode.t, xnode.flags);
  564.  
  565.           if (xnode.flags & epmask)
  566.             UpdateDisplay (0, 0, 1, 0, 1, color, board);
  567.           else
  568.             UpdateDisplay(xnode.f, xnode.t, 0, (short) xnode.flags & cstlmask, 0,
  569.                            color, board);
  570.           return (true);
  571.         }
  572.     }
  573.   return (false);
  574. }
  575.  
  576. void
  577. ShowResults (score, bstline, ch)
  578.      short int score;
  579.      short unsigned int *bstline;
  580.      char ch;
  581. {
  582.   short d, e, ply;
  583.   theScore = score;
  584.   if (showvalue) UpdateValue(0L,5);
  585.   if (post)
  586.     {
  587.       GrafPtr SavePort;
  588.       short h,v;
  589.       
  590.        GetPort(&SavePort);
  591.       SetPort(WindThink);
  592.       TextMode(srcCopy);
  593.  
  594.       d = 0;
  595.       
  596.       h = ThinkRec[computer].left+2;
  597.       v = ThinkRec[computer].top+15;
  598.       
  599.       for (ply = 1; bstline[ply] > 0; ply++)
  600.     {
  601.       algbr (bstline[ply] >> 8, bstline[ply] & 0xFF, false);
  602.       strcpy(ThinkMove[computer][d]+1, mvstr[0]);
  603.       ThinkMove[computer][d][0] = strlen(mvstr[0]);
  604.       MoveTo(h,v);
  605.       DrawString(ThinkMove[computer][d]);
  606.       if (++d>maxThink) break;
  607.       v += 12;
  608.     }
  609.       lpost = d;
  610.       while (d <= maxThink)
  611.     {
  612.       MoveTo(h,v);
  613.       ThinkMove[computer][d++][0] = 0;
  614.       v += 12;
  615.       DrawString("\p       ");
  616.     }
  617.     SetPort(SavePort);
  618.     }
  619. }
  620.  
  621.  
  622. void
  623. SearchStartStuff (side)
  624.      short int side;
  625. {
  626.   short i;
  627.   
  628.   SetPort(WindThink);
  629.   ThinkMove[side][0][0] = 0;
  630.   EraseRect(&ThinkRec[side]);
  631. }
  632.  
  633. void
  634. OutputMove ()
  635. {
  636.   short i;
  637.   StringHandle theString;
  638.  
  639.   ShowCMessage(""); 
  640.   if (SqAtakd (PieceList[!towho][0], towho))
  641.   {
  642.       theString = GetString(_CHECK_STR);
  643.       HLock((Handle)theString);
  644.     ShowPMessage(*(char **)theString);
  645.     HUnlock((Handle)theString);
  646.   }
  647.   
  648.   AddMove(GameCnt, mvstr[(root->flags & cstlmask) != 0]);
  649.   
  650.   for (i=0; i<64; i++) {
  651.       saveBoard[i] = board[i];
  652.       saveColor[i] = color[i];
  653.   }
  654.   
  655.   if (root->flags & epmask)
  656.     UpdateDisplay (0, 0, 1, 0, 1, color, board);
  657.   else
  658.     UpdateDisplay (root->f, root->t, 0, root->flags & cstlmask, 1, color, board);
  659.  
  660.   if (root->flags & draw) {      
  661.     theString = GetString(_DRAWN_STR);
  662.       HLock((Handle)theString);
  663.     ShowPMessage(*(char **)theString);
  664.     HUnlock((Handle)theString);
  665.     drawn = true;
  666.   }
  667.   else if (root->score == -9999) {
  668.     theString = GetString(_MATE_STR);
  669.       HLock((Handle)theString);
  670.     ShowPMessage(*(char **)theString);
  671.     HUnlock((Handle)theString);
  672.   }
  673.   else if (root->score == 9998) {
  674.     theString = GetString(_MATE_STR);
  675.       HLock((Handle)theString);
  676.     ShowPMessage(*(char **)theString);
  677.     HUnlock((Handle)theString);
  678.   }
  679.   else if (root->score < -9000) {
  680.     theString = GetString(_SOON_STR);
  681.       HLock((Handle)theString);
  682.     ShowPMessage(*(char **)theString);
  683.     HUnlock((Handle)theString);
  684.   }
  685.   else if (root->score > 9000) {
  686.     theString = GetString(_SOON_STR);
  687.       HLock((Handle)theString);
  688.     ShowPMessage(*(char **)theString);
  689.     HUnlock((Handle)theString);
  690.   }
  691. }
  692.  
  693. void
  694. ElapsedTime(iop)
  695.      short int iop;
  696. /*
  697.   Determine the time that has passed since the search was started. If
  698.   the elapsed time exceeds the target (ResponseTime+ExtraTime) then set
  699.   timeout to true which will terminate the search.
  700. */
  701. {
  702.   static unsigned long LastClick = 0;
  703.   
  704.   et = (TickCount() - time0)/60;
  705.   if (et < 0) {
  706.       et = 0;
  707.   }
  708.   if (((TickCount()-LastClick)>10) && (towho == computer || bothsides || preview)) {
  709.       if (mainLoop()) timeout = true;
  710.       LastClick = TickCount();
  711.   }
  712.  
  713.   ETnodes += 50;
  714.   if (et > et0 || iop == 1)
  715.     {
  716.       if (et > ResponseTime + ExtraTime && Sdepth > 1)
  717.             timeout = true;
  718.       et0 = et;
  719.       if (iop == 1)
  720.       {
  721.             time0 = TickCount();
  722.             et0 = 0;
  723.       }
  724.       if (et > 0)
  725.             /* evrate is Nodes / cputime */
  726.             evrate = NodeCnt / (et + ft);
  727.       else    evrate = 0;
  728.       
  729.       ETnodes = NodeCnt + 50;
  730.       UpdateClocks ();
  731.     }
  732.     
  733. }
  734.  
  735. void
  736. UpdateClocks ()
  737. {    
  738.     static unsigned long LastDraw = 0;
  739.     static int LastColor = black;
  740.     
  741.     if (LastColor!=towho || TickCount()-LastDraw>45) {
  742.             UpdateChronos(NULL, 0);
  743.             LastDraw = TickCount(); LastColor = towho;
  744.     }
  745. }
  746.  
  747.  
  748. void
  749. SetTimeControl (color)
  750. {
  751.   if (TCflag[color])
  752.     {
  753.       TimeControl.moves[color] = TCmoves[color];
  754.       TimeControl.clock[color] = 60 * (long) TCminutes[color];
  755.     }
  756.   else
  757.     {
  758.       TimeControl.moves[color] = 0;
  759.       TimeControl.clock[color] = 0;
  760.       Level[color] = 60 * (long) TCminutes[color];
  761.     }
  762.   et = 0;
  763.   ElapsedTime (1);
  764. }
  765.  
  766.  
  767. void
  768. Undo ()
  769. /*
  770.   Undo the most recent half-move.
  771.   */
  772. {
  773.   short f, t, i;
  774.   
  775.   RemoveMove(GameCnt);
  776.   f = GameList[GameCnt].gmove >> 8;
  777.   t = GameList[GameCnt].gmove & 0xFF;
  778.   if (board[t] == king && distance (t, f) > 1)
  779.     {
  780.         castle (GameList[GameCnt].color, f, t, 2);
  781.           DrawPieces (PieceToNum(color[t], board[t]), t);
  782.           DrawPieces (PieceToNum(color[f], board[f]), f);    
  783.           if (distance(t,f) == 2) {
  784.               DrawPieces (PieceToNum(color[t+1], board[t+1]), t+1);
  785.               DrawPieces (PieceToNum(color[t-1], board[t-1]), t-1);
  786.           } else {
  787.               DrawPieces (PieceToNum(color[t+1], board[t+1]), t+1);
  788.               DrawPieces (PieceToNum(color[t-2], board[t-2]), t-2);
  789.           }    
  790.     }
  791.   else
  792.     {
  793.       board[f] = board[t];
  794.       color[f] = color[t];
  795.       board[t] = GameList[GameCnt].piece;
  796.       color[t] = GameList[GameCnt].color;
  797.       DrawPieces(PieceToNum(color[t], board[t]), t);
  798.       DrawPieces(PieceToNum(color[f], board[f]), f);
  799.     }
  800.   if (TCflag[color[f]])
  801.     ++TimeControl.moves[color[f]];
  802.   GameCnt--;
  803.   drawn = mate = false;
  804.   Sdepth = 0;
  805.   Mvboard[f]--;
  806.   for (i=0; i<64; i++) {
  807.       saveColor[i] = color[i];
  808.       saveBoard[i] = board[i];
  809.   }
  810.   InitializeStats ();
  811. }
  812.  
  813. void
  814. ShowCurrentMove (pnt, f, t)
  815.      short int pnt;
  816.      short int f;
  817.      short int t;
  818. {
  819. }
  820.  
  821.  
  822. void
  823. GiveHint ()
  824. {
  825.   char s[40];
  826.   short f, t;
  827.   
  828.   if (!hint) return;
  829.   
  830.   f = hint >> 8;
  831.   t = hint & 0xFF;
  832.   
  833.   algbr ((short) f, (short) t, false);
  834.   ShowCMessage (mvstr[0]);
  835.   AnimePieces(0,PieceToNum(saveColor[f], saveBoard[f]),f, t, 1);
  836.   AnimePieces(PieceToNum(saveColor[t], saveBoard[t]),
  837.                 PieceToNum(saveColor[f], saveBoard[f]),
  838.                     t, f, 1);
  839. }
  840.  
  841.  
  842. void
  843. InputCommand ()
  844. /*
  845.   Process the users command. If easy mode is OFF (the computer is
  846.   thinking on opponents time) and the program is out of book, then make
  847.   the 'hint' move on the board and call SelectMove() to find a response.
  848.   The user terminates the search by entering ^C (quit siqnal) before
  849.   entering a command. If the opponent does not make the hint move, then
  850.   set Sdepth to zero.
  851.   */
  852. {
  853.   short ok, i, tmp;
  854.   long cnt, rate, t1, t2;
  855.   unsigned short mv;
  856.   char s[80];
  857.  
  858.   ok = quit = false;
  859.  
  860.   player = opponent = towho;
  861.   computer = !towho;
  862.   
  863.   ft = 0;
  864.   if (hint > 0 && !easy && Book == NULL)
  865.     {
  866.       preview = 1; idoit = 0;
  867.       time0 = TickCount();
  868.       algbr (hint >> 8, hint & 0xFF, false);
  869.       strcpy (s, mvstr[0]);
  870.       tmp = epsquare;
  871.       if (VerifyMove (s, 1, &mv))
  872.       {
  873.             SelectMove (computer, 2);
  874.             VerifyMove (mvstr[0], 2, &mv);
  875.             if (Sdepth > 0)
  876.                 Sdepth--;
  877.       }
  878.       ft = (TickCount() - time0)/60;
  879.       epsquare = tmp;
  880.       preview = 0;
  881.     }
  882.  
  883.   ok = idoit;
  884.   while (!(ok || quit))
  885.   {
  886.         ElapsedTime(0);
  887.       ok = mainLoop();
  888.   }
  889.   ElapsedTime(1);
  890.   ShowCMessage("");
  891. }
  892.  
  893. static void mouseToXY(Point pt, short *OuX, short *OuY)
  894. {
  895.     *OuX = (pt.h/(width-1))+1;
  896.     *OuX = scrntoxy(*OuX);
  897.     *OuY= 8 - (pt.v/(height-1));
  898.     *OuY = scrntoxy(*OuY);
  899. }
  900.  
  901.  
  902. static void followMouse(short *x1, short *y1, Point *Dum)
  903. {
  904.     do {
  905.         GetMouse(Dum);
  906.         PicInRect(&chessRectOff, myDragStuff, Dum);
  907.         mouseToXY(*Dum,x1,y1);
  908.         if ((MouseX!= *x1) || (MouseY != *y1))
  909.         {
  910.             MouseX = *x1; MouseY = *y1;
  911.             UpdateCase(0L,4);
  912.         }
  913.         else
  914.         {
  915.             MouseX = *x1; MouseY = *y1;
  916.         }
  917.         DragItTo(myDragStuff,*Dum,1, FALSE);
  918.          ElapsedTime (0);
  919.     } while (StillDown());
  920. }
  921.  
  922. static void playTheMove(short sq, short x1, short y1, Point Dum)
  923. {
  924.     Point theEnd;
  925.     Rect r;
  926.     
  927.     theEnd = CenterRect(Rectangle(scrntoxy(x1),scrntoxy(9-y1), &r));
  928.     DrawPieces(no_piece, sq);
  929.     DragFromTo(myDragStuff, Dum, theEnd);
  930.     DisposeDraggable(myDragStuff);
  931. }
  932.  
  933.  
  934.  
  935. short MouseInContent(Point MouseLoc, short *eatit)            
  936. {
  937.     short x,y,x1,y1,i,j,ok;
  938.     
  939.     ok = 0;
  940.     if (FrontWindow()==WindList) {
  941.         SetPort(WindList);
  942.         GlobalToLocal(&MouseLoc);
  943.         if (PtInRect(MouseLoc, &theBar)) LClick(MouseLoc, 0, List);
  944.         LocalToGlobal(&MouseLoc);
  945.     } else
  946.     if ((FrontWindow()==WindBoard) && (((opponent == towho) && (!bothsides))
  947.                                     || force) )
  948.     {
  949.         SetPort(WindBoard);
  950.         GlobalToLocal(&MouseLoc);
  951.         mouseToXY(MouseLoc,&x,&y);
  952.         if (y>=1 && y<=8)
  953.          {
  954.              Rect r;
  955.              short Num;
  956.              
  957.              short sq = (y-1)*8+x-1;
  958.              short sq1;
  959.              
  960.              MouseX=x;MouseY=y; UpdateCase(0L,4);
  961.             SetRect(&r,0,0,8*(width-1),8*(height-1));
  962.             if ((saveBoard[sq]!=no_piece)&&(saveColor[sq]==towho))
  963.             {
  964.                 Point Dum;
  965.                 PicHandle h1, h2;
  966.                 char s[6];
  967.                 unsigned short mv;
  968.                 
  969.                 if (preview) {
  970.                     *eatit = false;
  971.                     return 1;
  972.                 }
  973.  
  974.                  Num=PieceToNum(saveColor[sq],saveBoard[sq]);
  975.                 DrawPieces(no_piece ,sq);
  976.                 
  977.                 Dum=MouseLoc;
  978.                 h1=GetPicture(Num);
  979.                 HNoPurge((Handle)(h1));
  980.                 h2=GetPicture(Num-1+Num%4);
  981.                 HNoPurge((Handle)(h1));
  982.         
  983.                 NewDraggable(h1,h2,0L,0L, &myDragStuff);
  984.         
  985.                 HPurge((Handle)(h1));
  986.                 HPurge((Handle)(h2));
  987.         
  988.                  ShadowStuff.visible = 1;
  989.                  ShadowStuff.dx = 4;
  990.                  ShadowStuff.dy = 4;
  991.         
  992.                 followMouse(&x1, &y1, &Dum);
  993.  
  994.                 sq1 = (y1-1)*8+x1-1;
  995.                 if ((saveBoard[sq]==king) && (x1-x == 2)) strcpy(s,"o-o");
  996.                 else 
  997.                 if ((saveBoard[sq]==king) && (x-x1 == 3)) strcpy(s,"o-o-o");
  998.                 else {
  999.                     s[0] = x+'a'-1;
  1000.                     s[1] = y+'0';
  1001.                     s[2] = x1+'a'-1;
  1002.                     s[3] = y1+'0';
  1003.                     if (saveBoard[sq] == pawn && (y1 == 8 || y1 == 1)) {
  1004.                             s[4] = choosePromo();
  1005.                             s[5] = 0;
  1006.                     } else  s[4] = 0;
  1007.                 }
  1008.                 
  1009.                 if (ok = VerifyMove(s, 1, &mv)) {
  1010.                       if (mv != hint)
  1011.                     {
  1012.                       Sdepth = 0;
  1013.                       ft = 0;
  1014.                     }
  1015.                     VerifyMove (s, 2, &mv);
  1016.                     playTheMove(sq, x1, y1, Dum);
  1017.                     VerifyMove (s, 0, &mv);
  1018.                     DrawPieces(PieceToNum(color[sq1], board[sq1]), sq1);
  1019.                     AddMove(GameCnt, s);
  1020.                 } else /* Not valid... Go back home */
  1021.                     {
  1022.                         Rect r;
  1023.                         Point theEnd;
  1024.                         theEnd = CenterRect(Rectangle(scrntoxy(x),scrntoxy(9-y), &r));
  1025.                         DragFromTo(myDragStuff,Dum,theEnd);
  1026.                         DisposeDraggable(myDragStuff);
  1027.                     }
  1028.         } else while (StillDown());
  1029.         LocalToGlobal(&MouseLoc);
  1030.     }
  1031. }
  1032.     return ok;
  1033. }
  1034.  
  1035. short ProcessMenu_in(long CodeWord)
  1036. {
  1037.     MenuHandle MenuTopic;
  1038.     short Menu_No;
  1039.     short Item_No;
  1040.     Str255 NameHolder;
  1041.     short wind,i,Err;
  1042.     Rect nulrec;
  1043.     Handle ItemHdl;
  1044.     
  1045.     short ok = 0;
  1046.     if (CodeWord)
  1047.         {
  1048.         short change = false;
  1049.         Menu_No=HiWord(CodeWord);
  1050.         Item_No=LoWord(CodeWord);
  1051.  
  1052.         switch (Menu_No) {
  1053.  
  1054.             case AppleMenu:
  1055.                 if (Item_No==1) {
  1056.                     Alert(_ABOUT_ALRT, NULL);
  1057.                 }
  1058.                 else {
  1059.                     GetItem(GetMHandle(AppleMenu),Item_No,NameHolder);
  1060.                     OpenDeskAcc(NameHolder);
  1061.                 }
  1062.                 break;
  1063.             case FileMenu:
  1064.                 switch (Item_No) {
  1065.                 case 1:
  1066.                     if (!AreYouSure(_END_STR)) break;
  1067.                     newgame = 1;
  1068.                     donotplay = 1;
  1069.                     ok = true;
  1070.                     break;
  1071.                 case 2:
  1072.                     if (!AreYouSure(_END_STR)) break;
  1073.                     getgame = 1;
  1074.                     donotplay = 1;
  1075.                     ok = true;
  1076.                     break;
  1077.                 case 3:
  1078.                     SaveGame();
  1079.                     break;
  1080.                 case 5:
  1081.                     ListGame();
  1082.                     break;
  1083.                 case 7:
  1084.                     if (!AreYouSure(_END_STR)) break;
  1085.                     donotplay = 1;
  1086.                     quit = true;
  1087.                     ok = true;
  1088.                     break;
  1089.                 }
  1090.                 break;
  1091.  
  1092.             case EditMenu:
  1093.                 if (!SystemEdit(Item_No-1))
  1094.                     switch (Item_No) {
  1095.                         case 1:
  1096.                             if (GameCnt >= 0) {
  1097.                                 undo = 1;
  1098.                                 donotplay = 1;
  1099.                                 Sdepth = 0;
  1100.                                 ok = 1;
  1101.                             }
  1102.                             break;
  1103.                 }
  1104.                 break;
  1105.             case PlayerMenu:
  1106.                 switch (Item_No) {
  1107.                     case 1:
  1108.                         donotplay = true;
  1109.                         bothsides = false;
  1110.                         computer = black;
  1111.                         opponent = white;
  1112.                         ok = true;
  1113.                         force = false;
  1114.                         Sdepth = 0;
  1115.                         break;
  1116.                     case 2:
  1117.                         donotplay = true;
  1118.                         bothsides = false;
  1119.                         computer = white;
  1120.                         opponent = black;
  1121.                         ok = true;
  1122.                         force = false;
  1123.                         Sdepth = 0;
  1124.                         break;
  1125.                     case 3:
  1126.                         donotplay = true;
  1127.                         bothsides = true;
  1128.                         computer = towho;
  1129.                         opponent = !towho;
  1130.                         Sdepth = 0;
  1131.                         ok = true;
  1132.                         force = false;
  1133.                         break;
  1134.                     case 4:
  1135.                         force = true;
  1136.                         bothsides = false;
  1137.                         donotplay = true;
  1138.                         computer = !towho;
  1139.                         opponent = towho;
  1140.                         Sdepth = 0;
  1141.                         ok = true;
  1142.                         break;
  1143.                 }
  1144.                 if (Item_No>0 && Item_No<5)
  1145.                       for (i=1; i<=4; i++)
  1146.                           CheckItem(GetMHandle(Menu_No), i, i==Item_No);
  1147.                 break;
  1148.             case WhiteMenu:
  1149.             case BlackMenu:
  1150.               switch (Item_No)
  1151.                 {
  1152.                   
  1153.                 case 1:
  1154.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1155.                   TCminutes[Menu_No==WhiteMenu?white:black] = 5;
  1156.                   change = true;
  1157.                   break;
  1158.                 case 2:
  1159.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1160.                   TCminutes[Menu_No==WhiteMenu?white:black] = 15;
  1161.                   change = true;
  1162.                   break;
  1163.                 case 3:
  1164.                   TCmoves[Menu_No==WhiteMenu?white:black] = 60;
  1165.                   TCminutes[Menu_No==WhiteMenu?white:black] = 30;
  1166.                   change = true;
  1167.                   break;
  1168.                 case 4:
  1169.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1170.                   TCminutes[Menu_No==WhiteMenu?white:black] = 30;
  1171.                   change = true;
  1172.                   break;
  1173.                 case 5:
  1174.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1175.                   TCminutes[Menu_No==WhiteMenu?white:black] = 60;
  1176.                   change = true;
  1177.                   break;
  1178.                 case 6:
  1179.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1180.                   TCminutes[Menu_No==WhiteMenu?white:black] = 120;
  1181.                   change = true;
  1182.                   break;
  1183.                 case 7:
  1184.                   TCmoves[Menu_No==WhiteMenu?white:black] = 40;
  1185.                   TCminutes[Menu_No==WhiteMenu?white:black] = 240;
  1186.                   change = true;
  1187.                   break;
  1188.                 case 8:
  1189.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1190.                   TCminutes[Menu_No==WhiteMenu?white:black] = 15;
  1191.                   change = true;
  1192.                   break;
  1193.                 case 9:
  1194.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1195.                   TCminutes[Menu_No==WhiteMenu?white:black] = 60;
  1196.                   change = true;
  1197.                   break;
  1198.                 case 10:
  1199.                   TCmoves[Menu_No==WhiteMenu?white:black] = 1;
  1200.                   TCminutes[Menu_No==WhiteMenu?white:black] = 600;
  1201.                   change = true;
  1202.                   break;
  1203.                 case 12:
  1204.                   change = chooseTime((short *) (&TCmoves[Menu_No==WhiteMenu?white:black])
  1205.                                   ,(short *) (&TCminutes[Menu_No==WhiteMenu?white:black]));
  1206.                   break;
  1207.                 }
  1208.             
  1209.               if (change) {
  1210.                   for (i=1; i<=12; i++)
  1211.                       CheckItem(GetMHandle(Menu_No), i, i==Item_No);
  1212.                   SetTimeControl (Menu_No==WhiteMenu?white:black);
  1213.               }
  1214.               break;
  1215.             case OptionsMenu:
  1216.                 switch (Item_No) {
  1217.                     case 1:
  1218.                         easy = !easy;
  1219.                         CheckItem(GetMHandle(Menu_No), Item_No, easy);
  1220.                         break;
  1221.                     case 2:
  1222.                         reverse = !reverse;
  1223.                         UpdateDisplay(0, 0, 1, 0, 1, saveColor, saveBoard);
  1224.                         CheckItem(GetMHandle(Menu_No), Item_No, reverse);
  1225.                         break;
  1226.                     case 3:
  1227.                         anim = !anim;
  1228.                         CheckItem(GetMHandle(Menu_No), Item_No, anim);
  1229.                         break;
  1230.                     case 4:
  1231.                         dither = dither?0:6;
  1232.                         CheckItem(GetMHandle(Menu_No), Item_No, dither!=0);
  1233.                         break;
  1234.                     case 5:
  1235.                         post = !post;
  1236.                         CheckItem(GetMHandle(Menu_No), Item_No, post);
  1237.                         break;
  1238.                     case 6:
  1239.                         showvalue = !showvalue;
  1240.                         CheckItem(GetMHandle(Menu_No), Item_No, showvalue);
  1241.                         break;
  1242. #ifdef HASHFILE
  1243.                     case 7:
  1244.                         hashflag = !hashflag;
  1245.                         if (hashflag) hashflag = CheckHashFile();
  1246.                         CheckItem(GetMHandle(Menu_No), Item_No, hashflag);
  1247.                         break;
  1248. #endif
  1249.                     case 8:
  1250.                         break;
  1251.                     case 9:
  1252.                         GiveHint();
  1253.                         break;
  1254.                     case 10:
  1255.                         timeout = true;
  1256.                         ok = true;
  1257.                         break;
  1258.                 }
  1259.         }
  1260.  
  1261.         HiliteMenu(0);
  1262.     }
  1263.     return ok;
  1264. }
  1265.  
  1266. short DealwthMouseDowns(EventRecord *Event, short *eatit)
  1267. {
  1268.     short Location;
  1269.     WindowPtr WindowPointedTo;
  1270.     Point MouseLoc,theEnd;
  1271.     short WindoLoc;
  1272.     long Hw,NS;
  1273.     Rect r,rDum;
  1274.     short x,y,x1,y1,i,j;
  1275.     RgnHandle rg;
  1276.     Point Dum;
  1277.     Str255 C;
  1278.     Boolean Bool;
  1279.     short Item,ItemType,Num;
  1280.     Handle ItemHdl;
  1281.     PicHandle h1,h2;
  1282.  
  1283.     *eatit = true;
  1284.     MouseLoc = Event->where;
  1285.     WindoLoc = FindWindow(MouseLoc,&WindowPointedTo);
  1286.     switch (WindoLoc) {
  1287.         case inMenuBar:
  1288.             return ProcessMenu_in((long)MenuSelect(MouseLoc));
  1289.             break;
  1290.         case inSysWindow:
  1291.             SystemClick(Event,WindowPointedTo);
  1292.             break;
  1293.         case inContent:
  1294.             if (WindowPointedTo != FrontWindow()) 
  1295.                 SelectWindow(WindowPointedTo);
  1296.             else return MouseInContent(MouseLoc, eatit);
  1297.             break;
  1298.         case inGrow:
  1299.             if (WindowPointedTo != FrontWindow())
  1300.                 SelectWindow(WindowPointedTo);
  1301.             else
  1302.                 {
  1303.                 Hw = GrowWindow(WindowPointedTo, MouseLoc, &GrowArea);
  1304.                 SizeWindow(WindowPointedTo,Hw & 0xFFFF, Hw>>16, 1);
  1305.                 r = WindowPointedTo->portRect;
  1306.                 ClipRect(&r);
  1307.                 EraseRect(&r);
  1308.                 InvalRect(&r);
  1309.                 }
  1310.                 break;
  1311.         case inDrag:
  1312.                 DragWindow(WindowPointedTo,MouseLoc,&DragArea);
  1313.                 break;
  1314.  
  1315.         case inGoAway:
  1316.                 if (TrackGoAway(WindowPointedTo,MouseLoc))
  1317.                     HideWindow(WindowPointedTo);
  1318.                 break;
  1319.         case inZoomIn:
  1320.         case inZoomOut:
  1321.                 if  (WindowPointedTo != FrontWindow())
  1322.                     SelectWindow(WindowPointedTo);
  1323.                 else
  1324.                 {
  1325.                 ZoomWindow(WindowPointedTo,WindoLoc,1);
  1326.                 r =WindowPointedTo->portRect;
  1327.                 Hw = r.bottom - r.top;
  1328.                 NS = Hw>>16 + r.right - r.left;
  1329.                 if (NS)
  1330.                 {
  1331.                 SizeWindow(WindowPointedTo,NS & 0xFFFF,NS>>16,1);
  1332.                 r = WindowPointedTo->portRect;
  1333.                 ClipRect(&r);
  1334.                 EraseRect(&r);
  1335.                 InvalRect(&r);
  1336.                 }
  1337.                 }
  1338.                 break;
  1339.     }        
  1340.     return 0;
  1341. }
  1342.  
  1343.  
  1344. void DealWthNull(EventRecord *Event)
  1345. {
  1346.     WindowPtr WindowPointedTo;
  1347.     Point MouseLoc;
  1348.     short WindoLoc;
  1349.     short x,y;
  1350.     Boolean Update;
  1351.  
  1352.     WindoLoc=FindWindow(MouseLoc=Event->where,&WindowPointedTo);
  1353.     
  1354.     if ((WindoLoc==inContent) && (WindowPointedTo==WindBoard))
  1355.     {
  1356.         SetPort(WindBoard);
  1357.         GlobalToLocal(&MouseLoc);
  1358.         mouseToXY(MouseLoc,&x,&y);
  1359.         if (y>0 && y<9 && x>0 && x<9)
  1360.         {
  1361.             Update=(MouseX!=x) || (MouseY!=y);
  1362.             MouseX=x;
  1363.             MouseY=y;
  1364.             if (Update) {
  1365.                 UpdateCase(0L,4);
  1366.             }
  1367.         }
  1368.     }
  1369. }
  1370.  
  1371. int mainLoop()
  1372. {
  1373.     EventRecord evt;
  1374.     short ok, eatit, res, item;
  1375.     DialogPtr dlog;
  1376.     char theChar;
  1377.     
  1378.     res = 0;
  1379.     
  1380.     if (wne)
  1381.         ok = WaitNextEvent(everyEvent, &evt, 0L, NULL);
  1382.     else {
  1383.         SystemTask();
  1384.         ok = GetNextEvent(everyEvent, &evt);
  1385.     }
  1386.     if (!ok) {
  1387.         if (force || (towho == opponent)) DealWthNull(&evt);
  1388.         return 0;
  1389.     }
  1390.  
  1391.     eatit = preview;
  1392.     
  1393.     switch (evt.what) {
  1394.         case mouseDown:
  1395.             res = DealwthMouseDowns(&evt, &eatit);
  1396.             break;
  1397.         case keyDown:
  1398.         case autoKey: 
  1399.             theChar = evt.message & charCodeMask;
  1400.             if ((evt.modifiers & cmdKey) != 0) 
  1401.             res = ProcessMenu_in( MenuKey( theChar ));
  1402.             break;
  1403.         case activateEvt: 
  1404.             break;
  1405.         case updateEvt:
  1406.             break;
  1407.         case 15 : /* Multifinder Event */
  1408.             if ((evt.message & 0xFF000000) != 0xFA000000) {
  1409.                         background = !(evt.message & 1);
  1410.             }
  1411.             break;
  1412.         default:
  1413.             break;
  1414.     }
  1415.  
  1416.     if (IsDialogEvent(&evt)) {
  1417.         DialogSelect(&evt, &dlog, &item);
  1418.     }
  1419.  
  1420.     if (!eatit && preview) {
  1421.         static EvQEl globEvt;
  1422.         /* We re-post the event. */
  1423.         globEvt.qType = evType;
  1424.         globEvt.evtQWhat = evt.what;
  1425.         globEvt.evtQMessage = evt.message;
  1426.         globEvt.evtQWhen = evt.when;
  1427.         globEvt.evtQWhere.h = evt.where.h;
  1428.         globEvt.evtQWhere.v = evt.where.v;
  1429.         globEvt.evtQModifiers = evt.modifiers;
  1430.         Enqueue((QElemPtr)&globEvt, (QHdrPtr)GetEvQHdr());
  1431.     }
  1432.     return res;
  1433. }
  1434.  
  1435.  
  1436. loop()
  1437. {
  1438.   short i;
  1439.   
  1440.   SetCursor(*ClockCursor);
  1441.   towho = white;
  1442.   opponent = white;
  1443.   computer = black;
  1444.   bothsides = false;
  1445.   force = reverse = post = easy = false;
  1446.   hashflag = false;
  1447.   drawn = 0;
  1448.   NewGame();
  1449.   for (i=0; i<64; i++) {
  1450.       saveBoard[i] = board[i];
  1451.       saveColor[i] = color[i];
  1452.   }
  1453.   theScore = 0;
  1454.   UpdateValue(NULL, 0);
  1455.   *Msg = 0;
  1456.   UpdateMsg(NULL, 3);
  1457.   
  1458.   UpdateDisplay(0,0,1,0,1,color,board);
  1459.   undo = getgame = newgame = preview = 0;
  1460.   while (!(quit))
  1461.     {
  1462.       player = towho;
  1463.       if (force)
  1464.       {
  1465.           opponent = player;
  1466.           computer = otherside[player];
  1467.       }
  1468.       if (bothsides)
  1469.       {
  1470.           computer = player;
  1471.           opponent = otherside[player];
  1472.       }
  1473.      
  1474.       UpdateMenus();
  1475.       
  1476.       if (undo) {
  1477.               Undo();
  1478.               undo = 0;
  1479.               towho = !towho;
  1480.           }
  1481.           if (getgame) {
  1482.             SetCursor(*ClockCursor);
  1483.             Sdepth = 0;
  1484.             GetGame();
  1485.               getgame = 0;
  1486.           }
  1487.           if (newgame) {
  1488.             SetCursor(*ClockCursor);
  1489.               LDelRow(0, 0, List);
  1490.             NewGame();
  1491.             for (i=0; i<64; i++) {
  1492.                   saveColor[i] = color[i];
  1493.                   saveBoard[i] = board[i];
  1494.             }
  1495.             UpdateDisplay(0,0,1,0,1,color,board);
  1496.             towho = white;
  1497.             if (force) {
  1498.                 computer = !towho;
  1499.                 opponent = towho;
  1500.             }
  1501.             if (bothsides) {
  1502.                 computer = towho;
  1503.                 opponent = !towho;
  1504.             }
  1505.             Sdepth = 0;
  1506.               newgame = 0;
  1507.               drawn = 0;
  1508.           }
  1509.           
  1510.       if (mate || drawn)
  1511.           mainLoop();
  1512.       else {
  1513.         if (towho == white)
  1514.                   SetCursor(*ArrowCursor);
  1515.           else    SetCursor(&qd.arrow);
  1516.           
  1517.  
  1518.           for (i=0; i<64; i++) {
  1519.               saveBoard[i] = board[i];
  1520.               saveColor[i] = color[i];
  1521.         }
  1522.  
  1523.           if (((towho == opponent) && !bothsides) || force)
  1524.                   InputCommand();
  1525.           else    SelectMove (towho, 1);
  1526.           
  1527.           if (!donotplay) {
  1528.               towho = !towho;
  1529.         } else donotplay = 0;
  1530.       }
  1531.     }
  1532. }
  1533.  
  1534.